import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:graphic/graphic.dart';

import '../data.dart';
import 'ListModel.dart';

/// 十字线功能演示页面
class CrosshairPage extends StatefulWidget {
  const CrosshairPage({Key? key}) : super(key: key);

  @override
  CrosshairPageState createState() => CrosshairPageState();
}

/// 十字线页面状态管理类
class CrosshairPageState extends State<CrosshairPage> {
  /// 页面的 Scaffold Key
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  /// 用于在价格图表和成交量图表之间共享手势事件的流控制器
  final priceVolumeStream = StreamController<GestureEvent>.broadcast();

  /// 标签内边距常量
  static const _labelPadding = 6.0;

  /// 价格图表的十字线样式配置
  /// 数组包含两个元素，分别对应 X 轴和 Y 轴的样式
  final List<PaintStyle?> _showCrosshairOnPrice = [
    PaintStyle(strokeColor: Colors.black), // X 轴十字线样式
    PaintStyle(strokeColor: Colors.black), // Y 轴十字线样式
  ];

  /// 价格图表是否显示标签
  final List<bool> _showLabelOnPrice = [true, true];

  /// 价格图表十字线是否跟随指针
  final List<bool> _followPointerOnPrice = [false, false];

  /// 价格图表标签内边距
  final List<double> _labelPaddingOnPrice = [0.0, 0.0];

  ListModel? listModel;

  // 用于存储当前选中的数据
  Data? _selectedData;

  // 图表的key，用于获取图表状态
  final GlobalKey _chartKey = GlobalKey();

  // 用于监听LineMark选中事件的流控制器
  final StreamController<Map<String, Set<int>>?> _lineMarkSelectionStream =
  StreamController<Map<String, Set<int>>?>.broadcast();

  Future<void> initData() async {
    // 直接构造测试数据而不是从文件加载
    try {
      setState(() {
        listModel = ListModel(
          code: "0",
          message: "成功",
          data: [
            Data(amount: 100, date: "2025-01-01"),
            Data(amount: 120, date: "2025-01-02"),
            Data(amount: 80, date: "2025-01-03"),
            Data(amount: 150, date: "2025-01-04"),
            Data(amount: 200, date: "2025-01-05"),
            Data(amount: 180, date: "2025-01-06"),
            Data(amount: 160, date: "2025-01-07"),
            Data(amount: 140, date: "2025-01-08"),
            Data(amount: 170, date: "2025-01-09"),
            Data(amount: 190, date: "2025-01-10"),
            Data(amount: 210, date: "2025-01-11"),
            Data(amount: 230, date: "2025-01-12"),
            Data(amount: 250, date: "2025-01-13"),
            Data(amount: 220, date: "2025-01-14"),
            Data(amount: 240, date: "2025-01-15"),
            Data(amount: 260, date: "2025-01-16"),
            Data(amount: 280, date: "2025-01-17"),
            Data(amount: 300, date: "2025-01-18"),
            Data(amount: 290, date: "2025-01-19"),
            Data(amount: 270, date: "2025-01-20"),
          ],
        );
      });
    } catch (e) {
      // 处理错误情况
      debugPrint('Error creating data: $e');
    }
  }

  @override
  void initState() {
    // 监听LineMark的选中事件
    _lineMarkSelectionStream.stream.listen((selected) {
      _onLineMarkSelected(selected);
    });

    initData();
    super.initState();
  }

  @override
  void dispose() {
    // 释放资源
    _lineMarkSelectionStream.close();
    super.dispose();
  }

  // 处理LineMark选中事件
  void _onLineMarkSelected(Map<String, Set<int>>? selected) {
    debugPrint('LineMark选中事件: $selected');

    if (selected != null && selected.isNotEmpty && listModel?.data != null) {
      // 获取第一个选中项的数据
      final selectionName = selected.keys.first;
      final selectedIndices = selected[selectionName];

      if (selectedIndices != null && selectedIndices.isNotEmpty) {
        final index = selectedIndices.first;

        // 确保索引在有效范围内
        if (index >= 0 && index < listModel!.data!.length) {
          final data = listModel!.data![index];

          setState(() {
            _selectedData = data;
          });

          debugPrint('选中的数据索引: $index');
          debugPrint('选中的数据内容: Date=${data.date}, Amount=${data.amount}');
        }
      }
    } else {
      // 没有选中数据时清空显示
      setState(() {
        _selectedData = null;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    // 十字线绘制样式
    final crosshairPaintStyle = PaintStyle(strokeColor: Colors.black);
    print('list: ${listModel?.data?.length}');
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        title: const Text('Crosshair'),
      ),
      backgroundColor: Colors.white,
      // 使用 Stack 布局，将控制面板和图表叠放在一起
      body: Stack(
        children: [
          // 可滚动的控制面板区域
          SingleChildScrollView(
            child: Center(
              child: Column(
                children: <Widget>[
                  // 为图表留出空间
                  const SizedBox(height: 300),
                  // 控制面板容器
                  Container(
                    padding: const EdgeInsets.fromLTRB(24, 32, 24, 32),
                    alignment: Alignment.centerLeft,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        // 显示当前选中的数据信息
                        if (_selectedData != null)
                          Container(
                            padding: const EdgeInsets.all(8.0),
                            margin: const EdgeInsets.only(bottom: 10),
                            decoration: BoxDecoration(
                              color: Colors.grey[200],
                              borderRadius: BorderRadius.circular(4),
                            ),
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                const Text(
                                  '选中数据:',
                                  style: TextStyle(
                                    fontWeight: FontWeight.bold,
                                  ),
                                ),
                                Text('日期: ${_selectedData?.date ?? ""}'),
                                Text('金额: ${_selectedData?.amount ?? 0}'),
                              ],
                            ),
                          ),
                        // 价格图表十字线显示开关
                        _SwitchPair(
                          title: '• show crosshair on price',
                          valueX: _showCrosshairOnPrice[0] != null,
                          onChangedX: (isOn) => setState(() =>
                          _showCrosshairOnPrice[0] =
                          isOn ? crosshairPaintStyle : null),
                          valueY: _showCrosshairOnPrice[1] != null,
                          onChangedY: (isOn) => setState(() =>
                          _showCrosshairOnPrice[1] =
                          isOn ? crosshairPaintStyle : null),
                        ),
                        const Divider(),
                        // 价格图表十字线跟随指针开关
                        _SwitchPair(
                          title: '• follow pointer on price',
                          valueX: _followPointerOnPrice[0],
                          onChangedX: (isOn) =>
                              setState(() => _followPointerOnPrice[0] = isOn),
                          valueY: _followPointerOnPrice[1],
                          onChangedY: (isOn) =>
                              setState(() => _followPointerOnPrice[1] = isOn),
                        ),
                        const Divider(),
                        // 价格图表标签显示开关
                        _SwitchPair(
                          title: '• show label on price',
                          valueX: _showLabelOnPrice[0],
                          onChangedX: (isOn) =>
                              setState(() => _showLabelOnPrice[0] = isOn),
                          valueY: _showLabelOnPrice[1],
                          onChangedY: (isOn) =>
                              setState(() => _showLabelOnPrice[1] = isOn),
                        ),
                        const Divider(),
                        // 价格图表标签内边距开关
                        _SwitchPair(
                          title: '• show label padding on price',
                          valueX: _labelPaddingOnPrice[0] != 0.0,
                          onChangedX: (isOn) => setState(() =>
                          _labelPaddingOnPrice[0] =
                          isOn ? _labelPadding : 0.0),
                          valueY: _labelPaddingOnPrice[1] != 0.0,
                          onChangedY: (isOn) => setState(() =>
                          _labelPaddingOnPrice[1] =
                          isOn ? _labelPadding : 0.0),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ),
          // 图表显示区域

          listModel?.data?.isEmpty ?? true
              ? Container(
              padding: const EdgeInsets.only(top: 10),
              color: Colors.white,
              width: 350,
              height: 150,
              child: const Center(
                child: Text('暂无数据'),
              ))
              : ListView(
            shrinkWrap: true,
            physics:
            const NeverScrollableScrollPhysics(), // 禁止滚动，避免与外层滚动冲突
            children: [
              // 标题区域
              Container(
                color: Colors.white,
                padding: const EdgeInsets.fromLTRB(20, 40, 20, 5),
                child: const Text(
                  'Demo crosshair feature',
                  style: TextStyle(fontSize: 20),
                ),
              ),
              // 价格图表区域
              Container(
                padding: const EdgeInsets.only(top: 10),
                color: Colors.white,
                width: 350,
                height: 150,
                child: Chart(
                  key: _chartKey,
                  padding: (_) => const EdgeInsets.fromLTRB(60, 5, 10, 0),
                  rebuild: false,
                  // 禁止重建以提高性能
                  data: listModel?.data ?? [],
                  // 使用导入的数据
                  variables: {
                    // 定义变量：日期（字符串类型）和金额（数值类型）
                    'date': Variable(
                      accessor: (dynamic map) => (map as Data).date ?? '',
                      scale: OrdinalScale(tickCount: 3), // 序数比例尺，显示3个刻度
                    ),
                    'amount': Variable(
                      accessor: (dynamic map) =>
                      (map as Data).amount ?? 0,
                      scale: LinearScale(
                          min: 0, tickCount: 5), // 线性比例尺，最小值为0，显示5个刻度
                    ),
                  },
                  marks: [
                    LineMark(
                      layer: 0, // 设置LineMark的层级为0
                      size: SizeEncode(value: 1), // 线条粗细为1
                      // 添加selectionStream参数以监听选中事件
                      selectionStream: _lineMarkSelectionStream,
                      shape: ShapeEncode(
                          value: BasicLineShape(smooth: false)),
                    ),
                    // 添加点标记，用于在选中时显示为空心圆
                    PointMark(
                      layer: 1, // 设置PointMark的层级为1，使其显示在LineMark之上
                      size: SizeEncode(
                        value: 4, // 默认点大小
                        // 选中时更新点的大小
                        updaters: {
                          'touchMove': {
                            true: (double value) => 8, // 选中时大小为8
                            false: (double value) => 4, // 未选中时大小为6
                          }
                        },
                      ),
                      shape: ShapeEncode(
                        value: CircleShape(hollow: true, strokeWidth: 1.5),
                        updaters: {
                          'touchMove': {
                            true: (Shape shape) => CircleShape(hollow: true, strokeWidth: 3),
                            false: (Shape shape) => CircleShape(hollow: true, strokeWidth: 1.5),
                          }
                        },
                      ),
                      color: ColorEncode(
                        value: const Color(0xFF2A6BFD), // 默认颜色
                        // 选中时更新颜色
                        // updaters: {
                        //   'touchMove': {
                        //     true: (Color color) => Colors.orange, // 选中时橙色
                        //     false: (Color color) => Colors.blue, // 未选中时蓝色
                        //   }
                        // },
                      ),
                    ),
                    // 添加一个实心小白点来遮挡线条
                    PointMark(
                      layer: 2, // 设置为最高层级，确保完全遮挡线条
                      size: SizeEncode(
                        value: 2, // 小白点大小
                        updaters: {
                          'touchMove': {
                            true: (double value) => 4, // 选中时大小为4
                            false: (double value) => 2, // 未选中时大小为2
                          }
                        },
                      ),
                      shape: ShapeEncode(
                        value: CircleShape(hollow: false), // 实心圆
                      ),
                      color: ColorEncode(
                        value: Colors.white, // 白色填充
                      ),
                    )
                  ],
                  axes: [
                    // 配置坐标轴：隐藏水平轴的标签和线条
                    // Defaults.horizontalAxis
                    //   ..label = null
                    //   ..line = null,
                    // 显示水平坐标轴
                    Defaults.horizontalAxis,
                    // 垂直轴显示网格线，但第一条线（index==0）不显示
                    AxisGuide(
                      label: LabelStyle(
                        textStyle: Defaults.textStyle,
                        offset: const Offset(-7.5, 0),
                      ),
                      gridMapper: (_, index, __) =>
                      index == 0 ? null : PaintStyle(
                        strokeColor: Defaults.strokeColor,
                        strokeWidth: 1,
                        dash: [2, 2],
                      ),
                    ),
                  ],
                  selections: {
                    // 定义点选择交互，支持缩放更新、点击按下和长按移动更新手势
                    'touchMove': PointSelection(
                      on: {
                        GestureType.scaleUpdate,
                        GestureType.tapDown,
                        GestureType.longPressMoveUpdate
                      },
                      clear: {
                        GestureType.tapCancel,
                        GestureType.longPressEnd,
                        GestureType.scaleEnd
                      },
                      dim: Dim.x, // 仅在 X 轴方向进行选择
                    )
                  },
                  tooltip: TooltipGuide(
                    followPointer: [false, false],
                    align: Alignment.topLeft,
                    offset: const Offset(-20, -20),
                  ),
                  // 十字线配置，使用页面状态中的配置
                  crosshair: CrosshairGuide(
                    labelPaddings: [6.0, 6.0],
                    showLabel: [true, true],
                    labelBackgroundStyles: [
                      PaintStyle(
                        fillColor: Colors.green,
                      ),
                      PaintStyle(
                        fillColor: Colors.green,
                      )
                    ],
                    styles: [
                      PaintStyle(strokeColor: Colors.black, dash: [2, 2]),
                      // X 轴十字线样式（横线）
                      PaintStyle(strokeColor: Colors.black, dash: [2, 2]),
                      // Y 轴十字线样式（竖线）
                    ],
                  ),
                  // 共享手势事件流
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

/// 一对开关控件，用于同时控制 X 轴和 Y 轴的设置
class _SwitchPair extends StatelessWidget {
  const _SwitchPair({
    required this.title,
    required this.valueX,
    required this.onChangedX,
    required this.valueY,
    required this.onChangedY,
  });

  /// 控件标题
  final String title;

  /// X 轴开关当前值
  final bool valueX;

  /// X 轴开关值改变回调
  final void Function(bool) onChangedX;

  /// Y 轴开关当前值
  final bool valueY;

  /// Y 轴开关值改变回调
  final void Function(bool) onChangedY;

  @override
  Widget build(BuildContext context) {
    return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
      // 显示标题
      Text(
        title,
      ),
      // 水平排列 X 轴和 Y 轴的开关控件
      Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          _SwitchRow(
            text: 'on X-axis',
            value: valueX,
            onChanged: onChangedX,
          ),
          _SwitchRow(
            text: 'on Y-axis',
            value: valueY,
            onChanged: onChangedY,
          ),
        ],
      ),
    ]);
  }
}

/// 单个开关控件，包含文本标签和开关
class _SwitchRow extends StatelessWidget {
  const _SwitchRow(
      {required this.text, required this.value, required this.onChanged});

  /// 显示文本
  final String text;

  /// 开关当前值
  final bool value;

  /// 开关值改变回调
  final void Function(bool) onChanged;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        // 显示文本标签
        Text(
          text,
        ),
        // 开关控件，使用自适应样式并缩小显示
        Transform.scale(
          scale: 0.8,
          child: Switch.adaptive(
            value: value,
            onChanged: onChanged,
          ),
        ),
      ],
    );
  }
}
